package com.gcu.drivingschool.controller;

import cn.dev33.satoken.secure.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.gcu.drivingschool.common.utils.FileUtil;
import com.gcu.drivingschool.domain.dto.PageBean;
import com.gcu.drivingschool.domain.dto.UpdateCoachDto;
import com.gcu.drivingschool.domain.dto.UpdateStudentDto;
import com.gcu.drivingschool.domain.po.Coach;
import com.gcu.drivingschool.domain.po.Student;
import com.gcu.drivingschool.domain.vo.Result;
import com.gcu.drivingschool.service.CoachService;
import com.gcu.drivingschool.service.StudentService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.qiniu.common.QiniuException;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;

/**
 * 教练控制器
 * @author zzr
 * @create 2024-05-08-20:29
 */
@Tag(name = "教练控制器", description = "教练控制器")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/coaches")
public class CoachController {
    private final CoachService coachService;

    /**
     * 注册教练
     *
     * @param coach
     * @return
     */
    @Operation(summary = "注册教练", description = "注册教练,不允许手机号重复注册")
    @PostMapping
    public Result registerCoach(@RequestBody @Validated Coach coach) {
        coach.setCreateTime(new Date());
        coach.setPassword(BCrypt.hashpw(coach.getPassword(), BCrypt.gensalt(12)));//密码加密
        try {
            coachService.save(coach);
            return Result.success();
        } catch (DuplicateKeyException e) {
            return Result.fail("手机号已经注册");
        }
    }

    /**
     * 删除教练
     *
     * @param id
     * @return
     */
    @Parameter(name = "id", description = "教练id", in = ParameterIn.PATH, required = true)
    @Operation(summary = "删除教练", description = "删除教练")
    @DeleteMapping("/{id}")
    public Result delCoach(@PathVariable("id") Integer id) {
        boolean remove = coachService.removeById(id);
        if (!remove) {
            return Result.fail();
        }
        return Result.success();
    }

    /**
     * 获取教练信息列表
     * @param pageNum
     * @param pageSize
     * @param telephone
     * @param name
     * @param id_number
     * @param age
     * @param sex
     * @param type
     * @param carNumber
     * @param carType
     * @return
     */
    @Parameters({
            @Parameter(name = "pageNum", description = "第几页", in = ParameterIn.QUERY),
            @Parameter(name = "pageSize", description = "每页条数", in = ParameterIn.QUERY),
            @Parameter(name = "id", description = "教练id", in = ParameterIn.QUERY),
            @Parameter(name = "telephone", description = "手机号", in = ParameterIn.QUERY),
            @Parameter(name = "name", description = "姓名", in = ParameterIn.QUERY),
            @Parameter(name = "id_number", description = "身份证号", in = ParameterIn.QUERY),
            @Parameter(name = "age", description = "年龄", in = ParameterIn.QUERY),
            @Parameter(name = "sex", description = "性别", in = ParameterIn.QUERY),
            @Parameter(name = "type", description = "类型（手动档/自动档）", in = ParameterIn.QUERY),
            @Parameter(name = "carNumber", description = "车牌号", in = ParameterIn.QUERY),
            @Parameter(name = "carType", description = "车型", in = ParameterIn.QUERY)
    })
    @Operation(summary = "获取教练信息列表", description = "填哪些参数代表根据这些参数查，哪些参数不填代表所有<br/>" +
            "自行组合...")
    @GetMapping
    public Result getStudentList(@RequestParam(required = false) Integer pageNum,
                                 @RequestParam(required = false) Integer pageSize,
                                 @RequestParam(required = false) Integer id,
                                 @RequestParam(required = false) String telephone,
                                 @RequestParam(required = false) String name,
                                 @RequestParam(required = false) String id_number,
                                 @RequestParam(required = false) Integer age,
                                 @RequestParam(required = false) String sex,
                                 @RequestParam(required = false) String type,
                                 @RequestParam(required = false) String carNumber,
                                 @RequestParam(required = false) String carType) {
        //如果不传pageNum和pageSize,不分页
        if (pageNum == null) {
            pageNum = 1;
        }
        if (pageSize == null) {
            pageSize = Integer.MAX_VALUE;
        }
        LambdaQueryWrapper<Coach> wrapper = new LambdaQueryWrapper<>();
        wrapper
                .select(Coach::getId,Coach::getTelephone,Coach::getName,Coach::getIdNumber, Coach::getAge,
                        Coach::getSex,Coach::getPhoto,Coach::getType,Coach::getCarNumber,Coach::getCarType,Coach::getCreateTime)
                .eq(id != null,Coach::getId,id)
                .eq(StringUtils.isNotBlank(telephone), Coach::getTelephone, telephone)
                .eq(StringUtils.isNotBlank(name), Coach::getName, name)
                .eq(StringUtils.isNotBlank(id_number), Coach::getIdNumber, id_number)
                .eq(age != null, Coach::getAge, age)
                .eq(StringUtils.isNotBlank(sex), Coach::getSex, sex)
                .eq(StringUtils.isNotBlank(type), Coach::getType, type)
                .eq(StringUtils.isNotBlank(carNumber), Coach::getCarNumber, carNumber)
                .eq(StringUtils.isNotBlank(carType), Coach::getCarType, carType);
        PageHelper.startPage(pageNum, pageSize);//分页
        //查询数据
        List<Coach> list = coachService.list(wrapper);
        Page p = (Page) list;
        PageBean pb = new PageBean(p.getTotal(), p.getResult());
        return Result.success(pb);
    }


    /**
     * 修改教练信息
     * @param coach
     * @return
     */
    @Operation(summary = "修改教练信息", description = "填哪些参数代表根据这些参数改，哪些参数不填代表所有<br/>" +
            "自行组合...")
    @PutMapping
    public Result updateStudent(@RequestBody @Validated UpdateCoachDto coach) {
        LambdaUpdateWrapper<Coach> wrapper = new LambdaUpdateWrapper<>();
        if (StringUtils.isNotBlank(coach.getPhoto())){
            String photo = coachService.getById(coach.getId()).getPhoto();
            try {
                FileUtil.del(photo);
            } catch (QiniuException e) {
                return Result.fail();
            }
            wrapper.set(Coach::getPhoto,coach.getPhoto());
        }
        wrapper.set(StringUtils.isNotBlank(coach.getTelephone()), Coach::getTelephone, coach.getTelephone())
                .set(StringUtils.isNotBlank(coach.getName()), Coach::getName, coach.getName())
                .set(StringUtils.isNotBlank(coach.getIdNumber()), Coach::getIdNumber, coach.getIdNumber())
                .set(coach.getAge() != null, Coach::getAge, coach.getAge())
                .set(StringUtils.isNotBlank(coach.getSex()), Coach::getSex, coach.getSex())
                .set(StringUtils.isNotBlank(coach.getPassword()), Coach::getPassword,
                        BCrypt.hashpw(coach.getPassword(),BCrypt.gensalt(12)))
                .set(StringUtils.isNotBlank(coach.getType()), Coach::getType, coach.getType())
                .set(StringUtils.isNotBlank(coach.getCarNumber()), Coach::getCarNumber, coach.getCarNumber())
                .set(StringUtils.isNotBlank(coach.getCarType()), Coach::getCarType, coach.getCarType())
                .eq(Coach::getId, coach.getId());
        boolean update = coachService.update(wrapper);
        if (!update){
            return Result.fail();
        }
        return Result.success();
    }
}
